package pl.elka.pszt.controller;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import pl.elka.pszt.controller.event.BaseEvent;
import pl.elka.pszt.controller.handler.Handlers;
import pl.elka.pszt.model.Model;
import pl.elka.pszt.view.View;

/**
 * Opowiada za obsluge eventow w aplikacji, inicjalizacje oraz zamkniecie modelu i widoku.
 * 
 * @author Andrzej Makarewicz
 * 
 */
public class Controller {
	
	/**
	 * Pomocnicza smienna ktora odpala domyslny test z modelu
	 */
	private static final boolean DEBUG_MODE = false;
	
	private final View view;
	private final Model model;
	private final BlockingQueue<BaseEvent> eventQueue;
	private final Handlers handlers;
	//
	private boolean isRunning = true;
	
	public Controller() {
		handlers = new Handlers(this);
		eventQueue = new LinkedBlockingQueue<BaseEvent>();
		model = new Model(this);
		
		if (DEBUG_MODE) {
			try {
				model.test();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		view = new View(this);
	}
	
	public void run() {
		while (isRunning) {
			try {
				BaseEvent event = eventQueue.take();
				handlers.handleEvent(event);
			}
			catch (final Handlers.NotHandledException e) {
				e.printStackTrace();
			}
			catch (InterruptedException e) {
				e.printStackTrace();
				isRunning = false;
			}
			catch (Exception e) {
				e.printStackTrace();
				isRunning = false;
			}
		}
		model.close();
		model.clear();
		view.dispose();
	}
	
	/**
	 * Zatrzymuje aplikacje po przetworzeniu ostatniego eventu.
	 */
	public void stopRunning() {
		isRunning = false;
	}
	
	/**
	 * 
	 * @return czy aplikacja dziala
	 */
	public boolean isRunning() {
		return isRunning;
	}
	
	public View getView() {
		return view;
	}
	
	public Model getModel() {
		return model;
	}
	
	public BlockingQueue<BaseEvent> getEventQueue() {
		return eventQueue;
	}
	
	public void onEvent(BaseEvent event) {
		eventQueue.offer(event);
	}
	
}
